package com.estate.framework.web.service.data;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.estate.common.core.domain.model.ApiResponse;
import com.estate.common.core.domain.model.listing.Address;
import com.estate.common.core.domain.model.listing.Agent;
import com.estate.common.core.domain.model.listing.Links;
import com.estate.common.core.domain.model.listing.ListingResp;
import com.estate.common.utils.DateUtils;
import com.estate.common.utils.SnowflakeIdWorker;
import com.estate.framework.web.pojo.ListingFilter;
import com.estate.framework.web.service.job.ExcuteListingSchduleTask;
import com.estate.system.domain.Listing;
import com.estate.system.service.impl.DataListingsServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class ZenuListingApi {

    private static final Logger log = LoggerFactory.getLogger(ExcuteListingSchduleTask.class);

    @Resource
    private DataListingsServiceImpl dataListingsServiceImpl;

    @Resource
    public ZenuApiClient client;

    public void saveBatchListings() {

//        log.info("开始保存房源数据");
        Integer count = countNewListings();

        // 同步数据记录
        client.syncDataRecord(count, "Listing Data", "success", "Listing", null);

        int pages = 0;
        if (count > 0) {
            pages = count % 10 == 0 ? count / 10 : count / 10 + 1;
        }
        for (int i = 0; i < pages; i++) {
            Map<String, String> filters = getListingFilter();
            List<Listing> clients = pageListingsInfo(filters, i + 1, 10);
            dataListingsServiceImpl.saveOrUpdateBatch(clients);
        }
//        log.info("保存房源数据结束");

    }

    /**
     * 获取过滤条件-当前日期
     *
     * @return 过滤条件
     */
    @NotNull
    private static Map<String, String> getListingFilter() {
        // 获取悉尼时区
        ZoneId sydneyZone = ZoneId.of("Australia/Sydney");

        // 获取悉尼当前日期和昨天的日期
        LocalDate sydneyToday = LocalDate.now(sydneyZone);
        LocalDate sydneyYesterday = sydneyToday.minusDays(1);

        // 设置开始时间为悉尼昨天00:00:00
        String startTime = sydneyYesterday.atStartOfDay(sydneyZone).format(DateTimeFormatter.ISO_DATE_TIME);

        // 设置结束时间为悉尼今天23:59:59
        String endTime = sydneyToday.atTime(23, 59, 59).atZone(sydneyZone).format(DateTimeFormatter.ISO_DATE_TIME);

        ListingFilter filters = new ListingFilter();
        filters.setUpdatedDateFrom(startTime);
        filters.setUpdatedDateTo(endTime);
        Map<String, String> filtersMap = new HashMap<>();

        //将filter转为Map<String, String>
        filtersMap.putAll(filters.toMap());

        return filtersMap;
    }

    private Integer countNewListings() {
        try {
            Map<String, String> filters = getListingFilter();
            ApiResponse<List<ListingResp>> response = client.getListings(1, 1, filters);
            Long totalRecords = response.getPagination().getTotalRecords();
            return totalRecords.intValue();
        } catch (IOException e) {
            log.error("API调用失败: " + e.getMessage());
            // 同步数据记录
            client.syncDataRecord(0, "Listing Data", "failed", "Listing", e.getMessage());
        }
        return 0;
    }


    /**
     * 带过滤条件的房源列表
     *
     * @param filters    过滤条件
     * @param pageNumber 页码
     * @param pageSize   每页大小
     * @return 房源列表
     */
    public List<Listing> pageListingsInfo(Map<String, String> filters, Integer pageNumber, Integer pageSize) {
        ZenuApiClient client = new ZenuApiClient();
        try {
//            log.info("=== 带过滤条件的房源列表 ===");

            ApiResponse<List<ListingResp>> filteredResponse = client.getListings(pageNumber, pageSize, filters);

            if (filteredResponse.getSuccess()) {
//                log.info("========>请求成功!总记录数: {};总页数: {};当前页: {};每页大小: {}", filteredResponse.getPagination().getTotalRecords(),
//                        filteredResponse.getPagination().getTotalPages(), filteredResponse.getPagination().getPageNumber(),
//                        filteredResponse.getPagination().getPageSize());

                List<ListingResp> filteredData = filteredResponse.getData();

                //获取所有的ID
                List<Integer> ids = filteredData.stream().map(ListingResp::getId).collect(Collectors.toList());
                //查询数据库是否存在
                QueryWrapper<Listing> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().in(Listing::getListingId, ids);
                List<Listing> existListings = dataListingsServiceImpl.list(queryWrapper);
                if (!existListings.isEmpty()) {
                    log.info("========>数据库已存在{}条数据,跳过", existListings.size());
                    List<Integer> existIds = existListings.stream().map(Listing::getListingId).collect(Collectors.toList());
                    dataListingsServiceImpl.removeByIds(existIds);
                    //去除filteredData中存在于existListings的数据
                    //filteredData = filteredData.stream().filter(listingResp -> !existIds.contains(listingResp.getId())).collect(Collectors.toList());
                }

                List<Listing> listings = new ArrayList<>();

                for (ListingResp listingResp : filteredData) {
                    Listing listing = new Listing();
                    listing.setId(SnowflakeIdWorker.getSingleton().nextId());
                    List<String> listingTypes = new ArrayList<>();
                    listingTypes.add(listingResp.getListingMethod());
                    listing.setListingType(JSONObject.toJSONString(listingTypes));
                    if (StringUtils.isNotEmpty(listingResp.getListedDate())) {
                        listing.setListedDate(DateUtils.parseISODate(listingResp.getListedDate()));
                    }
                    //listing.setUserId(Long.valueOf(listingResp.getUserId()));
                    listing.setListingStatus(listingResp.getListingStatus());
                    listing.setCreatedAt(new Date());
                    listing.setUpdatedAt(new Date());
                    listing.setLeaseTerm(listingResp.getLeaseLengthMonths() + "");
                    listing.setPropertyType(listingResp.getPropertyType());
                    listing.setListingCategory(listingResp.getPropertyCategory());
                    listing.setListingAddr(JSONObject.toJSONString(listingResp.getAddress()));
                    listing.setListingFeatures(JSONObject.toJSONString(listingResp.getFeatures()));
                    listing.setListingPrice(JSONObject.toJSONString(listingResp.getPrice()));
                    listing.setListingRates(JSONObject.toJSONString(listingResp.getRates()));
                    listing.setListingInspectionTimes(JSONObject.toJSONString(listingResp.getInspectionTimes()));
                    Links links = new Links();
                    links.setUrl(listingResp.getUrl());
                    links.setVideoUrl(listingResp.getVideoUrl());
                    links.setVirtualTourUrl(listingResp.getVirtualTourUrl());
                    links.setEmagUrl(listingResp.getEmagUrl());
                    links.setExternalUrl(listingResp.getExternalUrl());
                    links.setExternalUrl2(listingResp.getExternalUrl2());
                    listing.setListingLinks(JSONObject.toJSONString(links));
                    listing.setListingImages(JSONObject.toJSONString(listingResp.getImages()));
                    listing.setTimeline(JSONObject.toJSONString(listingResp.getTimeline()));
                    if (StringUtils.isNotEmpty(listingResp.getOnMarketDate())) {
                        listing.setOnMarketDate(DateUtils.parseISODate(listingResp.getOnMarketDate()));
                    }
                    if (StringUtils.isNotEmpty(listingResp.getAvailableDate())) {
                        listing.setAvailableDate(DateUtils.parseISODate(listingResp.getAvailableDate()));
                    }
                    listing.setIsHidden(listingResp.getIsHidden());
                    listing.setListingId(listingResp.getId());
                    listing.setAgent(JSONObject.toJSONString(listingResp.getAgents()));
                    listings.add(listing);
                }

                return listings;
            } else {
                StringBuilder errorMsg = new StringBuilder();
                errorMsg.append("========>请求失败!\n");
                if (filteredResponse.getMessages() != null) {
                    filteredResponse.getMessages().forEach(msg -> errorMsg.append("\n").append(msg));
                }
                log.error(errorMsg.toString());
                // 同步数据记录
                client.syncDataRecord(0, "Listing Data", "failed", "Listing", errorMsg.toString());
            }

        } catch (IOException e) {
            log.error("API调用失败: " + e.getMessage());
            // 同步数据记录
            client.syncDataRecord(0, "Listing Data", "failed", "Listing", e.getMessage());
        }
        return null;
    }

    /**
     * 单个房源详情
     *
     * @param listingById 房源ID
     */
    public ListingResp singleListingsInfo(Integer listingById) {
        ZenuApiClient client = new ZenuApiClient();

        try {
            log.info("=== 获取单个房源详情 ===");
            ApiResponse<ListingResp> singleListingResponse = client.getListingById(listingById);

            if (singleListingResponse.getSuccess()) {
                ListingResp listingResp = singleListingResponse.getData();

                System.out.println("=== 房源详情 ===");
                System.out.println("ID: " + listingResp.getId());
                System.out.println("描述: " + (listingResp.getDescription() != null ?
                        listingResp.getDescription().substring(0, Math.min(100, listingResp.getDescription().length())) + "..." : "N/A"));
                System.out.println("地址: " + formatAddress(listingResp.getAddress()));
                System.out.println("状态: " + listingResp.getListingStatus());
                System.out.println("交易方式: " + listingResp.getListingMethod());
                System.out.println("类别: " + listingResp.getPropertyCategory());
                System.out.println("类型: " + listingResp.getPropertyType());

                return listingResp;
            } else {
                StringBuilder errorMsg = new StringBuilder();
                errorMsg.append("========>请求失败!\n");
                if (singleListingResponse.getMessages() != null) {
                    singleListingResponse.getMessages().forEach(msg -> errorMsg.append("\n").append(msg));
                }
                log.error(errorMsg.toString());
            }

        } catch (IOException e) {
            log.error("获取单个房源详情---API调用失败: " + e.getMessage());
        }
        return null;
    }

    private static String formatAddress(Address address) {
        if (address == null) return "N/A";

        StringBuilder sb = new StringBuilder();
        if (address.getUnitNumber() != null && !address.getUnitNumber().isEmpty()) {
            sb.append(address.getUnitNumber()).append("/");
        }
        sb.append(address.getStreetNumber()).append(" ")
                .append(address.getStreetName()).append(", ")
                .append(address.getSuburb()).append(" ")
                .append(address.getState()).append(" ")
                .append(address.getPostcode());

        return sb.toString();
    }

    public static void main(String[] args) {
        ZenuApiClient client = new ZenuApiClient();

        try {
            // 示例1: 基础获取房源列表
            log.info("=== 基础获取房源列表 ===");
            ApiResponse<List<ListingResp>> basicResponse = client.getListings();
            printListings(basicResponse);

            // 示例2: 带过滤条件的获取房源
//            log.info("\n=== 带过滤条件的房源列表 ===");
            Map<String, String> filters = new HashMap<>();
            filters.put("status", "On Market");
            filters.put("category", "Residential");
            filters.put("method", "Sale");

            ApiResponse<List<ListingResp>> filteredResponse = client.getListings(1, 10, null);
            printListings(filteredResponse);

            // 示例3: 获取单个房源详情
            log.info("\n=== 获取单个房源详情 ===");
            if (!filteredResponse.getData().isEmpty()) {
                Integer firstListingId = filteredResponse.getData().get(0).getId();
                ApiResponse<ListingResp> singleListing = client.getListingById(firstListingId);
                printListingDetail(singleListing.getData());
            }

        } catch (IOException e) {
            log.error("API调用失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void printListings(ApiResponse<List<ListingResp>> response) {
        if (response.getSuccess()) {
//            log.info("========>请求成功!总记录数: {};总页数: {};当前页: {};每页大小: {}", response.getPagination().getTotalRecords(),
//                    response.getPagination().getTotalPages(), response.getPagination().getPageNumber(),
//                    response.getPagination().getPageSize());

            for (ListingResp listingResp : response.getData()) {
                System.out.println("---");
                System.out.println("房源ID: " + listingResp.getId());
                System.out.println("地址: " + formatAddress(listingResp.getAddress()));
                System.out.println("状态: " + listingResp.getListingStatus());
                System.out.println("方式: " + listingResp.getListingMethod());
                System.out.println("价格: " + (listingResp.getPrice() != null ? listingResp.getPrice().getText() : "N/A"));
            }
        } else {
            StringBuilder errorMsg = new StringBuilder();
            errorMsg.append("========>请求失败!\n");
            if (response.getMessages() != null) {
                response.getMessages().forEach(msg -> errorMsg.append("\n").append(msg));
            }
            log.error(errorMsg.toString());
        }
    }

    private static void printListingDetail(ListingResp listingResp) {
        System.out.println("=== 房源详情 ===");
        System.out.println("ID: " + listingResp.getId());
        System.out.println("描述: " + (listingResp.getDescription() != null ?
                listingResp.getDescription().substring(0, Math.min(100, listingResp.getDescription().length())) + "..." : "N/A"));
        System.out.println("地址: " + formatAddress(listingResp.getAddress()));
        System.out.println("状态: " + listingResp.getListingStatus());
        System.out.println("交易方式: " + listingResp.getListingMethod());
        System.out.println("类别: " + listingResp.getPropertyCategory());
        System.out.println("类型: " + listingResp.getPropertyType());

        if (listingResp.getPrice() != null) {
            System.out.println("价格信息: " + listingResp.getPrice().getText());
            if (listingResp.getPrice().getFrom() != null) {
                System.out.println("价格范围: $" + listingResp.getPrice().getFrom() +
                        (listingResp.getPrice().getTo() != null ? " - $" + listingResp.getPrice().getTo() : "+"));
            }
        }

        if (listingResp.getAgents() != null && !listingResp.getAgents().isEmpty()) {
            System.out.println("关联经纪人:");
            for (Agent agent : listingResp.getAgents()) {
                System.out.println("  - " + agent.getFirstName() + " " + agent.getSurname() +
                        " (" + agent.getPosition() + ")");
            }
        }

        if (listingResp.getImages() != null && !listingResp.getImages().isEmpty()) {
            System.out.println("图片数量: " + listingResp.getImages().size());
        }
    }

}
